package com.gee.spring.cloud.aerospace.simulate.core.util;

import com.gee.cloud.common.core.util.json.JsonUtil;
import com.gee.spring.cloud.aerospace.simulate.core.domain.DslParam;
import com.gee.spring.cloud.aerospace.simulate.core.domain.TelemetryNodeDto;
import com.gee.spring.cloud.aerospace.simulate.core.satellite.telemetry.TmFrameGenerator;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotEmpty;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.hutool.core.text.StrPool.DOT;

/**
 * @author gepengjun
 * @since 2024/7/4 10:56
 */
public class TelemetryNodeUtil {


    public static void calNodeValue(TmFrameGenerator tmFrameGenerator, TelemetryNodeDto currentNode,
                                    List<TelemetryNodeDto> frameNodeList){
        Map<String, String> scriptParamMap = new HashMap<>();
        if (StringUtils.hasLength(currentNode.getDslParam())){
            JsonUtil.parseArray(currentNode.getDslParam(), DslParam.class)
                    .forEach(dslParam -> scriptParamMap.put(dslParam.getDslParamCode(), dslParam.getDslParamValue()));
        }
        try {
            Object calResult = DslUtil.invokeStatic(currentNode.getTelemetryDsl().getDslScript(), tmFrameGenerator,
                    currentNode, frameNodeList, scriptParamMap);
            currentNode.setBytes((byte[]) calResult);
        } catch (Exception e) {
            throw new RuntimeException(String.format("计算节点值出错： %s", currentNode.getNodeName()), e);
        }
    }

    public static TelemetryNodeDto getNode(@NotEmpty String path, @NotEmpty List<TelemetryNodeDto> telemetryNodeList){
        if (path.contains(DOT)){
            String currentNodeName = path.substring(0, path.indexOf(DOT));
            String leftPath = path.substring(path.indexOf(DOT) + 1);
            TelemetryNodeDto telemetryNode = telemetryNodeList.stream()
                    .filter(node -> node.getNodeName().equals(currentNodeName))
                    .findFirst()
                    .orElseThrow(() -> new RuntimeException("节点未找到:" + currentNodeName));
            return getNode(leftPath, telemetryNode.getChildrenDto());
        }
        return telemetryNodeList.stream()
                .filter(node -> node.getNodeName().equals(path))
                .findFirst()
                .orElseThrow(() -> new RuntimeException("节点未找到:" + path));
    }
}
